\subsection{Передача значений как указателей; тэггированные объединения}

Вот как можно передавать обычные значения как указатели:

\begin{lstlisting}[label=unsigned_multiply_C,style=customc]
#include <stdio.h>
#include <stdint.h>

uint64_t multiply1 (uint64_t a, uint64_t b)
{
	return a*b;
};

uint64_t* multiply2 (uint64_t *a, uint64_t *b)
{
	return (uint64_t*)((uint64_t)a*(uint64_t)b);
};

int main()
{
	printf ("%d\n", multiply1(123, 456));
	printf ("%d\n", (uint64_t)multiply2((uint64_t*)123, (uint64_t*)456));
};
\end{lstlisting}

Это работает нормально и GCC 4.8.4 компилирует обе ф-ции multiply1() и multiply2() полностью идентично!

\begin{lstlisting}[label=unsigned_multiply_lst,style=customasmx86]
multiply1:
	mov	rax, rdi
	imul	rax, rsi
	ret

multiply2:
	mov	rax, rdi
	imul	rax, rsi
	ret
\end{lstlisting}

Пока вы не разыменовываете указатель (\IT{dereference}) (иными словами, если вы не пытаетесь прочитать данные
по адресу в указателе), всё будет работать нормально.
Указатель это переменная, которая может содержать что угодно, как и обычная переменная.

\myindex{x86!\Instructions!MUL}
\myindex{x86!\Instructions!IMUL}
Здесь используется инструкция для знакового умножения (\IMUL) вместо беззнакового (\MUL), об этом читайте больше здесь:
\ref{IMUL_over_MUL}.

\myindex{Тэггированные указатели}
Кстати, это широко известный хак, называющийся \IT{tagged pointers}.
Если коротко, если все ваши указатели указывают на блоки в памяти размером, скажем, 16 байт (или они всегда
выровнены по 16-байтной границе), 4 младших бита указателя будут всегда нулевыми, и это пространство может быть
как-то использовано.
\myindex{LISP}
Это очень популярно в компиляторах и интерпретаторах LISP.
Они хранят тип ячейки/объекта в неиспользующихся битах, и так можно сэкономить немного памяти.
И более того --- имея только указатель, можно сразу выяснить тип ячейки/объекта, без дополнительного обращения к памяти.
Читайте об этом больше: \InSqBrackets{\CNotes 1.3}.

% TODO Example of tagged ptrs here

